<?php

namespace App\Console\Commands;

use App\Models\Agent;
use App\Models\Partner;
use Illuminate\Console\Command;

class RecalculateAgentRelationships extends Command
{
    /**
     * 命令名称及签名
     *
     * @var string
     */
    protected $signature = 'migrate:recalculate_agent_relationships';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '计算所有用户的上下级关系';

    protected $partners = [];

    public function handle()
    {
        // 现有的所有合伙人
        $this->partners = Partner::query()->pluck('agent_id')->toArray();
        // 所有代理总数
        $agentTotal = Agent::query()->count();

        $this->output->text('开始处理所有代理上级');
        $bar = $this->output->createProgressBar($agentTotal);
        Agent::query()->select(['id'])->eachById(function ($agentId) use ($bar) {
            $this->dealWithSigleAgent($agentId->id);
            $bar->advance();
        }, 2000);

        $this->output->text('开始处理所有代理邀请人数');
        $bar = $this->output->createProgressBar($agentTotal);
        Agent::query()->select(['id'])->eachById(function ($agent) use ($bar) {
            $agent->update([
                'number_of_direct_inviter' => Agent::query()->where('direct_inviter', $agent->id)->count(),
                'number_of_indirect_inviter' => Agent::query()->where('indirect_inviter', $agent->id)->count(),
            ]);
            $bar->advance();
        }, 2000);

        $this->output->success('完成');
    }

    private function dealWithSigleAgent($agentId)
    {
        // 重新计算直接邀请人 间接邀请人，跳过禁用的，递归上级
        $agent = Agent::query()->find($agentId, ['id', 'direct_inviter', 'status']);
        if ($agent['status'] === Agent::STATUS_DISABLE) {
            // 不处理禁用的上级关系, 跳过
            return;
        }

        // 有上级
        if (!empty($agent['direct_inviter'])) {
            $superior = []; // 所有上级, 越近的越靠前
            $this->recursivelyGetSuperior($agent['direct_inviter'], $superior);
            // 默认合伙人
            $affiliatedPartner = 0;

            if (in_array((int) $agentId, $this->partners, true)){
                //如果当前代理商是合伙人的话，则所属合伙人为自身
                $affiliatedPartner = $agentId;
            }else{
                // 最近的那个, 并且是合伙人, 则所属合伙人为他
                foreach ($superior as $parentAgentId) {
                    if (in_array((int) $parentAgentId, $this->partners, true)) {
                        $affiliatedPartner = $parentAgentId;
                        break;
                    }
                }
            }

            // 更新直接邀请人和间接邀请人
            $agent->update([
                'direct_inviter' => $superior[0] ?? 0,
                'indirect_inviter' => $superior[1] ?? 0,
                'affiliated_partner' => $affiliatedPartner, // 根据上级路径，计算所属合伙人
                'parent_path_id' => implode('-', array_reverse($superior)), // 绘制上级路线
            ]);
        }
    }

    /**
     * 递归上级
     * @param $directInviterId
     * @param $superior
     */
    private function recursivelyGetSuperior($directInviterId, &$superior)
    {
        $directInviter = Agent::query()->find($directInviterId, ['id', 'direct_inviter', 'status']);

        // 如果直接邀请人没被禁用
        if ($directInviter['status'] !== Agent::STATUS_DISABLE) {
            $superior[] = $directInviterId; // 存储上级用户 ID
        }

        // 直接邀请人还有上级, 继续往上一级
        if (!empty($directInviter['direct_inviter'])) {
            // 继续上一级
            $this->recursivelyGetSuperior($directInviter['direct_inviter'], $superior);
        }
    }
}
